﻿using System;
using System.Collections.Generic;
using Styx;
using Styx.WoWInternals.WoWObjects;

namespace SuperbadWoD
{
    internal class Feral
    {
        public static int active_enemies { get; set; }
        public static int combo_points { get; set; }
        public static double gcd { get; set; }
        public static double persistent_multiplier { get; set; }

        /* Do not update these variables in UpdateFeralVariables()! */
        public static WoWUnit RipCycleTarget { get; set; }
        public static WoWUnit RakeCycleTarget { get; set; }
        public static WoWUnit MoonfireCycleTarget { get; set; }
        public static WoWUnit FerociousBiteCycleTarget { get; set; }
        public static List<WoWUnit> CycleUnits { get; set; }

        public void UpdateFeralVariables()
        {
            active_enemies = active_enemies;
            combo_points = combo_points;
            gcd = gcd;
            persistent_multiplier = persistent_multiplier;
            cooldown.incarnation.remains = cooldown.incarnation.remains;
            cooldown.tigers_fury.remains = cooldown.tigers_fury.remains;
            energy.current = energy.current;
            energy.max = energy.max;
            energy.time_to_max = energy.time_to_max;
            talent.bloodtalons.enabled = talent.bloodtalons.enabled;
            talent.incarnation_king_of_the_jungle.enabled = talent.incarnation_king_of_the_jungle.enabled;
            target.health.pct = target.health.pct;
            target.time_to_die = target.time_to_die;
            dot.moonfire.duration = dot.moonfire.duration;
            dot.moonfire.remains = dot.moonfire.remains;
            dot.rake.duration = dot.rake.duration;
            dot.rake.pmultiplier = dot.rake.pmultiplier;
            dot.rake.remains = dot.rake.remains;
            dot.rip.duration = dot.rip.duration;
            dot.rip.pmultiplier = dot.rip.pmultiplier;
            dot.rip.remains = dot.rip.remains;
            dot.rip.ticking = dot.rip.ticking;
            dot.thrash_bear.duration = dot.thrash_bear.duration;
            dot.thrash_bear.remains = dot.thrash_bear.remains;
            dot.thrash_cat.duration = dot.thrash_cat.duration;
            dot.thrash_cat.remains = dot.thrash_cat.remains;
            prev.thrash_bear = prev.thrash_bear;
            buff.berserk.up = buff.berserk.up;
            buff.bloodtalons.up = buff.bloodtalons.up;
            buff.king_of_the_jungle.up = buff.king_of_the_jungle.up;
            buff.omen_of_clarity.react = buff.omen_of_clarity.react;
            buff.predatory_swiftness.remains = buff.predatory_swiftness.remains;
            buff.predatory_swiftness.up = buff.predatory_swiftness.up;
            buff.prowl.up = buff.prowl.up;
            buff.savage_roar.remains = buff.savage_roar.remains;
            buff.shadowmeld.up = buff.shadowmeld.up;
            buff.tigers_fury.up = buff.tigers_fury.up;
        }

        public static void FeralRotation()
        {
            if (buff.prowl.up || buff.shadowmeld.up)
                if (rake())
                    return;
            auto_attack();
            skull_bash();
            if(buff.berserk.up)
                if(incarnation())
                    return;
            if (cooldown.tigers_fury.remains < 8)
                if(berserk())
                    return;
            if (target.time_to_die <= 40)
                draenic_agility();
            if(buff.tigers_fury.up)
                use_item(WoWInventorySlot.Trinket1);
            if (buff.tigers_fury.up)
                blood_fury();
            if (buff.tigers_fury.up)
                berserking();
            if ((!buff.omen_of_clarity.react && energy.max - energy.current >= 60) | energy.max - energy.current >= 80)
                if(tigers_fury())
                    return;
            if (buff.savage_roar.remains < 3 || (buff.bloodtalons.up && buff.savage_roar.remains < 6))
                if (shadowmeld())
                    return;
            //TODO:CYCLE
            if (dot.rip.ticking && dot.rip.remains <= 3 && target.health.pct < 25)
                if (ferocious_bite())
                    return;
            if (talent.bloodtalons.enabled && buff.predatory_swiftness.up &&
                (combo_points >= 4 || buff.predatory_swiftness.remains < 1.5))
                if (healing_touch())
                    return;
            if (buff.savage_roar.remains < 3)
                if (savage_roar())
                    return;
            if (target.health.pct < 25 && buff.berserk.up)
                draenic_agility();
            if (buff.omen_of_clarity.react && dot.thrash_cat.remains <= dot.thrash_cat.duration*0.3 &&
                active_enemies > 1)
                if (thrash_cat())
                    return;
            //TODO: CYCLE
            if (combo_points == 5 && dot.rip.ticking && persistent_multiplier > dot.rip.pmultiplier)
                if (rip())
                    return;
            //TODO:CYCLE
            if (combo_points == 5 && target.health.pct < 25 && dot.rip.ticking)
                if (ferocious_bite())
                    return;
            //TODO:CYCLE
            if (combo_points == 5 && dot.rip.remains <= dot.rip.duration*0.3)
                if (rip())
                    return;
            if (combo_points == 5 && (energy.time_to_max <= 1 || buff.berserk.up || cooldown.tigers_fury.remains < 3) &&
                buff.savage_roar.remains < 42*0.3)
                if (savage_roar())
                    return;
            if (combo_points == 5 && (energy.time_to_max <= 1 || buff.berserk.up || cooldown.tigers_fury.remains < 3))
                if (ferocious_bite())
                    return;
            //TODO:CYCLE
            if (dot.rake.remains <= dot.rake.duration*0.3 && active_enemies < 9 && combo_points < 5)
                if (rake())
                    return;
            /* Pooling for Thrash */
            if (dot.thrash_cat.remains < 4.5 && active_enemies > 1 &&
                energy.current < Spell.CalculateSpellCost(SpellData.ThrashCat))
                return;
            if (dot.thrash_cat.remains < 4.5 && active_enemies > 1)
                if (thrash_cat())
                    return;
            //TODO:CYCLE
            if (persistent_multiplier > dot.rake.pmultiplier && active_enemies < 9 && combo_points < 5)
                if (rake())
                    return;
            //TODO:CYCLE
            if (dot.moonfire.remains <= dot.moonfire.duration*0.3 && active_enemies == 1)
                if (moonfire())
                    return;
            if (combo_points < 5 && active_enemies > 1)
                if (swipe())
                    return;
            if (combo_points < 5 && active_enemies == 1)
                if (shred())
                    return;
        }

        private static void skull_bash()
        {
            throw new NotImplementedException();
        }

        private static bool draenic_agility()
        {
            throw new NotImplementedException();
        }

        private static bool shred()
        {
            return Spell.Cast(SpellData.Shred);
        }

        private static bool swipe()
        {
            return Spell.Cast(SpellData.Swipe);
        }

        private static bool moonfire()
        {
            return Spell.Cast(SpellData.MoonfireFeral);
        }

        private static bool rip()
        {
            return Spell.Cast(SpellData.Rip);
        }

        private static bool thrash_cat()
        {
            return Spell.Cast(SpellData.ThrashCat);
        }

        private static bool berserk()
        {
            return Spell.Cast(SpellData.Berserk);
        }

        private static bool tigers_fury()
        {
            return Spell.Cast(SpellData.TigersFury);
        }

        private static void berserking()
        {
            Spell.Cast(SpellData.BerserkingFeral);
        }

        private static void blood_fury()
        {
            Spell.Cast(SpellData.BloodFuryFeral);
        }

        private static void use_item(WoWInventorySlot slot)
        {
            throw new NotImplementedException();
        }

        private static bool incarnation()
        {
            return Spell.Cast(SpellData.IncarnationFeral);
        }

        private static bool savage_roar()
        {
            return Spell.Cast(SpellData.SavageRoar);
        }

        private static bool healing_touch()
        {
            throw new NotImplementedException();
        }

        private static bool ferocious_bite()
        {
            return Spell.Cast(SpellData.FerociousBite);
        }

        private static bool shadowmeld()
        {
            return Spell.Cast(SpellData.Shadowmeld);
        }

        private static void auto_attack()
        {
            throw new NotImplementedException();
        }

        private static bool rake()
        {
            return Spell.Cast(SpellData.Rake);
        }

        public class buff
        {
            public class berserk
            {
                public static bool up { get; set; }
            }

            public class bloodtalons
            {
                public static bool up { get; set; }
            }

            public class king_of_the_jungle
            {
                public static bool up { get; set; }
            }

            public class omen_of_clarity
            {
                public static bool react { get; set; }
            }

            public class predatory_swiftness
            {
                public static bool up { get; set; }
                public static double remains { get; set; }
            }

            public class prowl
            {
                public static bool up { get; set; }
            }

            public class savage_roar
            {
                public static double remains { get; set; }
            }

            public class shadowmeld
            {
                public static bool up { get; set; }
            }

            public class tigers_fury
            {
                public static bool up { get; set; }
            }
        }

        public class cooldown
        {
            public class incarnation
            {
                public static double remains { get; set; }
            }

            public class tigers_fury
            {
                public static double remains { get; set; }
            }
        }

        public class dot
        {
            public class moonfire
            {
                public static double remains { get; set; }
                public static int duration { get; set; }
            }

            public class rake
            {
                public static double remains { get; set; }
                public static double pmultiplier { get; set; }
                public static int duration { get; set; }
            }

            public class rip
            {
                public static bool ticking { get; set; }
                public static double remains { get; set; }
                public static double pmultiplier { get; set; }
                public static int duration { get; set; }
            }

            public class thrash_bear
            {
                public static double remains { get; set; }
                public static int duration { get; set; }
            }

            public class thrash_cat
            {
                public static double remains { get; set; }
                public static int duration { get; set; }
            }
        }

        public class energy
        {
            public static double time_to_max { get; set; }
            public static int max { get; set; }
            public static int current { get; set; }
        }

        public class prev
        {
            public static bool thrash_bear { get; set; }
        }

        public class talent
        {
            public class bloodtalons
            {
                public static bool enabled { get; set; }
            }

            public class incarnation_king_of_the_jungle
            {
                public static bool enabled { get; set; }
            }
        }

        public class target
        {
            public static double time_to_die { get; set; }

            public class health
            {
                public static double pct { get; set; }
            }
        }
    }
}